#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <assert.h>
#include <math.h>

#include "graph.h"
#include "parse.h"
#include "mcmc.h"

/* path separator */
#ifndef PATHSEP
#define PATHSEP '/'
#endif

/* doesn't modify file_name, returns a pointer within it, assumes / as the
 * path separator */
char * my_basename(char * file_name)
{
  int last_sep = -1;
  int pos;
  
  assert(file_name != NULL);
  
  pos = 0;
  do {
    if (file_name[pos] == PATHSEP)
      last_sep = pos;

  } while (file_name[pos++]);
  
  return file_name + (last_sep+1);
}

int main(int argc, char ** argv)
{
  int start_time;
  int uai_time;
  double uai_memory;
  char * temp;
  char * model_fname;                        /* model file name */
  char * model_name;   /* model name -- basename of model file name */
  char * evidence_fname;
  int seed;
  char * taskstr;
  Task_t task;
  Graph_t * model;
  int num_inst;                             /* number of instances */
  Instance_t * p_inst;                       /* array of instances */
  char * out_fname;
  FILE * out_fp;

  /* record the initial time */
  start_time = (int) time(NULL);

  printf("%s\n", PACKAGE_STRING);
  
  /* read environment variables */
  temp = getenv("UAI_TIME");
  if (temp)
  {
    uai_time = (int) floor(atof(temp));
    printf("UAI_TIME = %d secs\n", uai_time);
  }
  else
  {
    fprintf(stderr, 
            "Warning: UAI_TIME not defined, defaulting to 20 (seconds)\n");
    uai_time = 20;
  }

  temp = getenv("UAI_MEMORY");
  if (temp)
  {
    uai_memory = atof(temp);
    printf("UAI_MEMORY = %g GB\n", uai_memory);
  }
  else
  {
    fprintf(stderr, "Warning: UAI_MEMORY not defined, defaulting to 1 (GB)\n");
    uai_memory = 1;
  }

  /* read the command line */

  if (argc != 5)
  {
    fprintf(stderr, "Error: expecting 5 arguments got %d\n", argc);
    return 1;
  }

  /* extract the command-line arguments */
  model_fname = argv[1];
  evidence_fname = argv[2];
  seed = atoi(argv[3]);
  taskstr = argv[4];

  /* set the seed for the random number generator */
  srand(seed);

  /* parse the model file */
  model = parse_model(model_fname);
  parse_evidence(evidence_fname, model, &num_inst, &p_inst);

  if (!strncmp(taskstr, "PR", 2))
  {
    task = Task_PR;
  }
  else if (!strncmp(taskstr, "MPE", 3))
  {
    task = Task_MPE;
  }
  else if (!strncmp(taskstr, "MAR", 3))
  {
    task = Task_MAR;
  }
  else if (!strncmp(taskstr, "BEL", 3))
  {
    task = Task_BEL;
  }
  else
  {
    fprintf(stderr, "Error: Unknown taskstr %s\n", taskstr);
    return 1;
  }

  model_name = my_basename(model_fname);
  
  out_fname = (char *)malloc(strlen(model_name) + 1 + strlen(taskstr) + 1);

  sprintf(out_fname, "%s.%s", model_name, taskstr);
  
  out_fp = fopen(out_fname, "w");

  fprintf(out_fp, "%s\n", taskstr);
  
  mcmc_main(model, num_inst, p_inst, task, start_time + uai_time, uai_memory,
            out_fp);
  
  fclose(out_fp);

  free(out_fname);

  printf("Elapsed %d seconds\n", ((int)time(NULL)) - start_time);
  
  /* TODO: free graph and instance memory */
  
  return 0;
}
